package com.gitee.swsk33.publishsubscribedemo.model;

import com.gitee.swsk33.publishsubscribedemo.model.prototype.Subscriber;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 事件总线<br>
 * 维护所有的主题对应的订阅者列表，并负责消息传递
 */
public class Broker {

	/**
	 * 存放每个时间话题对应的订阅者列表的哈希表
	 * <ul>
	 *     <li>键：话题，Topic</li>
	 *     <li>值：订阅这个话题的订阅者列表</li>
	 * </ul>
	 */
	private final Map<String, List<Subscriber>> subscriberMap;

	public Broker() {
		subscriberMap = new HashMap<>();
	}

	/**
	 * 增加一个订阅者
	 *
	 * @param topic      订阅的话题
	 * @param subscriber 订阅者对象
	 */
	public void subscribe(String topic, Subscriber subscriber) {
		if (!subscriberMap.containsKey(topic)) {
			subscriberMap.put(topic, new ArrayList<>());
		}
		subscriberMap.get(topic).add(subscriber);
	}

	/**
	 * 移除一个订阅者
	 *
	 * @param topic      订阅的话题
	 * @param subscriber 订阅者对象
	 */
	public void unsubscribe(String topic, Subscriber subscriber) {
		if (subscriberMap.containsKey(topic)) {
			subscriberMap.get(topic).remove(subscriber);
		}
	}

	/**
	 * 发布一个事件
	 *
	 * @param event 发布的事件对象
	 */
	public void publish(Event<?> event) {
		// 获取订阅这个事件话题的全部订阅者
		List<Subscriber> subscribers = subscriberMap.get(event.getTopic());
		for (Subscriber subscriber : subscribers) {
			// 传递事件对象给订阅者
			subscriber.onSubscribe(event);
		}
	}

}